<template>
    <!-- 搜索相关 start -->
    <el-form :model="queryParams" ref="refForm" size="default" :inline="true" v-show="showSearch" label-width="38px">
        <el-form-item label="中文名称" prop="name" label-width="70px">
            <el-input v-model="queryParams.name" placeholder="请输入中文名称" clearable @keyup.enter.native="handleGetList" />
        </el-form-item>
        <el-form-item label="英文名称" prop="enName" label-width="70px">
            <el-input v-model="queryParams.enName" placeholder="请输入英文名称" clearable
                @keyup.enter.native="handleGetList" />
        </el-form-item>
        <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="default" @click="handleGetList">搜索</el-button>
            <el-button type="primary" icon="el-icon-refresh" size="default" @click="resetForm(refForm)">重置</el-button>
        </el-form-item>
    </el-form>
    <!-- 搜索相关 end -->

    <!-- 操作相关 start -->
    <el-row :gutter="10" class="mb8" v-if="roleSinglePage">
        <el-col :span="1.5">
            <el-button type="primary" plain icon="el-icon-plus" size="default"
                @click="outerVisible = true; addOrUpdate = true">新增</el-button>
        </el-col>
        <el-col :span="1.5">
            <el-button type="success" plain icon="el-icon-edit" size="default" @click="handleUpdate"
                :disabled="true">修改</el-button>
        </el-col>
        <el-col :span="1.5">
            <el-button type="danger" plain icon="el-icon-delete" size="default" @click="handleDeleteConfirmEvent"
                :disabled="true">删除</el-button>
        </el-col>
        <el-col :span="1.5">
            <el-button type="warning" plain icon="el-icon-download" size="default" :disabled="true">导出</el-button>
        </el-col>
        <el-col :span="1.5">
            <el-button type="info" plain icon="el-icon-s-operation" size="default" :disabled="true">日志</el-button>
        </el-col>
        <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="handleGetList"></right-toolbar> -->
    </el-row>
    <!-- 操作相关 end -->

    <!-- 表格相关 start -->
    <el-table :data="filterTableData" style="width: 60%;height: 550px;" @select="getSelectedColumn" ref="tableRef">
        <el-table-column type="selection" width="55">
        </el-table-column>
        <el-table-column label="序号" type="index" width="55" :index="indexMethod" />
        <el-table-column label="中文名称" prop="name" width="70" />
        <el-table-column label="英文名称" prop="enName" width="120" show-overflow-tooltip />
        <el-table-column width="260">
            <template #header>
                <el-input v-model="search" size="small" placeholder="Type to search" />
            </template>
            <template #default="scope" v-if="roleSinglePage">
                <el-button type="primary" v-if="!scope.row.menuSetted"
                    @click="menuSetting(scope.$index, scope.row)">配置菜单</el-button>
                <el-button type="primary" :icon="Edit" @click="handleEdit(scope.$index, scope.row)" />
                <!-- <template #default="scope"> -->
                <el-popconfirm width="220" confirm-button-text="确定" cancel-button-text="取消" :icon="InfoFilled"
                    icon-color="#626AEF" title="确定删除此角色么？" @confirm="handleDeleteConfirmEvent(scope.$index, scope.row)">
                    <template #reference>
                        <el-button type="primary" :icon="Delete" />
                    </template>
                </el-popconfirm>
                <!-- </template> -->
            </template>
        </el-table-column>
    </el-table>
    <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
        :page-sizes="[10, 20, 50, 100, 200, 300, 400]" :small="small" :disabled="disabled" :background="background"
        layout="total, sizes, prev, pager, next, jumper" :total=pageData.totalNum @size-change="handleSizeChange"
        @current-change="handleCurrentChange" style="margin-top: 20px;" />
    <!-- 表格相关 end -->

    <el-form style="margin-top: 10px;" v-if="!roleSinglePage">
        <el-button type="primary" icon="el-icon-search" size="default" @click="userRoleSettingSubmit">角色配置保存</el-button>
    </el-form>

    <!-- 添加或修改参数配置对话框 start-->
    <el-dialog :title="title" width="500px" append-to-body draggable v-model="outerVisible">
        <el-row :gutter="15">
            <el-form :model="addFormData" :rules="rules" :size="formSize" label-width="150px" ref="addFormRef"
                style="max-width: 600px">
                <el-col :span="24">
                    <el-form-item label="中文名称" prop="name">
                        <el-input v-model="addFormData.name" placeholder="请输入中文名称"
                            :autosize="{ minRows: 4, maxRows: 4 }" :style="{ width: '100%' }"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="英文名称" prop="enName">
                        <el-input v-model="addFormData.enName" placeholder="请输入英文名称"
                            :autosize="{ minRows: 4, maxRows: 4 }" :style="{ width: '100%' }"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item size="large">
                        <el-button type="primary" @click="submitAddForm(addFormRef)">{{ addOrUpdate ? '保存' : '修改'
                            }}</el-button>
                        <el-button @click="outerVisible = false">取消</el-button>
                        <el-button @click="resetForm(addFormRef)">重置</el-button>
                    </el-form-item>
                </el-col>
            </el-form>
        </el-row>
    </el-dialog>
    <!-- 添加或修改参数配置对话框 end -->

    <!-- 配置菜单对话框 start-->
    <el-dialog :title="menuSettingTitle" width="500px" append-to-body draggable v-model="menuSettingOuterVisible"
        v-if="menuSettingOuterVisible">
        <Menu :singlePage="false" :roleId="currentRoleId" :selectedIdList="currentSelectedIdList"></Menu>
    </el-dialog>
    <!-- 配置菜单对话框 end -->

</template>

<script lang="ts" setup>
import { computed, ref, reactive, onMounted, toRaw } from 'vue'
import { showErrorMsg, showSuccessMsg, resetForm, indexMethod } from '@/api/common'
import type { FormInstance, FormRules, ComponentSize } from 'element-plus'
import { ElTable } from 'element-plus'
import { Delete, Edit, InfoFilled } from '@element-plus/icons-vue'
import { addRole, deleteRole, updateRole, pageRole, getSelectedMenuListByRoleId } from "@/api/role/role";
import { userRoleSetting } from "@/api/user/user";
import Menu from '../menu/Menu.vue';
import type { ApiResponse, PageData, PageResponse, OnlyIdRequest } from '@/api/common';
import type { Role, QueryParams, RoleAddRequest, MenuListRequest, UserRoleRequest } from '@/api/role/role'
const small = ref(false)
const background = ref(false)
const disabled = ref(false)
let title = ref('新增角色')
let menuSettingTitle = ref('菜单配置')
let outerVisible = ref(false)
let menuSettingOuterVisible = ref(false)
// 显示搜索条件
let showSearch = ref<boolean>(true)
const refForm = ref<FormInstance>()
// 默认新增
let addOrUpdate = ref<boolean>(true);
let onlyIdRequest = reactive<OnlyIdRequest>({
    id: 1,
})
let pageData = reactive<PageData<Role>>({
    totalNum: 0,
    tableData: [],
})
let queryParams = reactive<QueryParams>({
    pageNum: 1,
    pageSize: 10,
    name: '',
    enName: '',
})
let menuListRequest = reactive<MenuListRequest>({
    roleId: 1
})
const search = ref('')
const filterTableData = computed(() =>
    pageData.tableData.filter(
        (data) => !search.value ||
            data.name.toLowerCase().includes(search.value.toLowerCase()) ||
            data.enName.toLowerCase().includes(search.value.toLowerCase()))
)
const handleEdit = (index: number, row: Role) => {
    addFormData.id = row.id;
    addFormData.name = row.name;
    addFormData.enName = row.enName;
    addOrUpdate.value = false;
    outerVisible.value = true;
}
const handleDeleteConfirmEvent = (index: number, row: Role) => {
    onlyIdRequest.id = row.id;
    deleteRole(onlyIdRequest).then((res: ApiResponse<string>) => {
        console.log(res);
        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            showSuccessMsg("删除成功")
            handleGetList();
        }
    });
    // console.log(index, row.id)
}
const props = withDefaults(defineProps<{
    // 是否是从左侧菜单进入
    roleSinglePage: boolean,
    userId: number,
    selectedRoleIdList: number[],
}>(), {
    roleSinglePage: true,
})
// 已配置的角色设置勾选
const toggleSelection = (rows?: Role[]) => {
    if (rows) {
        rows.forEach((row) => {
            // TODO: improvement typing when refactor table
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-expect-error
            tableRef.value!.toggleRowSelection(row, undefined)
        })
    } else {
        tableRef.value!.clearSelection()
    }
}
// 监听 selectedIdList 的变化
// 这里拿到的pageData.tableData一直是空的，加的这个immediate: true ，watch 会在组件初始化时立即执行一次但是watch在onMounted前面执行了。
// 暂时改成延迟执行吧。
// 这里本质上只支持一个任务对应一个角色，所以传一个number就可以了，但是遇到一个问题：如果前后两次点击，两个人对应同一个角色，
// 那么子组件是无法监听到这个值的变化的，会出现理应勾选的角色，没有被勾选，即使前后两次点击，子组件经历了卸载到再加载。
// watch(() => props.selectedRoleId, (newVal) => {
//     // todo 这里有个隐患，因为获取pageData.tableData有网络延迟，如果长于50ms，那么可能会勾选失败。
//     setTimeout(() => {
//         let selectedRoleList = pageData.tableData.filter(data => {
//             if (data.id == newVal[0]) {
//                 return data;
//             }
//         });
//         // 设置被选中的菜单
//         toggleSelection(selectedRoleList);
//     }, 50);
// });
// 延迟勾选
const rowSelectTimeout = () => {
    setTimeout(() => {
        // props.selectedRoleIdList 其实是一个reactive对象，直接遍历是拿不到number元素的，它自身也相当于一个数组一样的，
        // 把number[] 放在了它的第一号元素位上。但是你通过props.selectedRoleIdList[0]去遍历又会报类型错误，因为编译器认为此时
        // 拿到的对象应该是一个number，而不是number[]，于是采用下面这种深拷贝方式去移除框架赋予它的额外类型。此时拿到的普通类型，
        // number[]仍然放在一号元素位上。但是此时deepCopySelectedRoleIdList[0]就能点出includes了。
        const deepCopySelectedRoleIdList = JSON.parse(JSON.stringify(props.selectedRoleIdList));
        let selectedRoleList = pageData.tableData.filter(data => {
            if (deepCopySelectedRoleIdList[0].includes(data.id)) {
                return data;
            }
        });
        toggleSelection(selectedRoleList);
    }, 50);
}
// }, { immediate: true });
const tableRef = ref<InstanceType<typeof ElTable>>()
let userRoleRequest = reactive<UserRoleRequest>({
    userId: null,
    roleIdList: [],
})
let tempRoleIdList = ref<number[]>([]);
const getSelectedColumn = (selection: Role[], row: Role) => {
    tempRoleIdList.value = [];
    selection.forEach(element => {
        tempRoleIdList.value.push(element.id);
    })
}
const userRoleSettingSubmit = () => {
    if (tempRoleIdList.value.length < 1) {
        showErrorMsg("至少选择一个角色！")
        return;
    }
    userRoleRequest.userId = props.userId;
    userRoleRequest.roleIdList = tempRoleIdList.value;
    userRoleSetting(userRoleRequest).then((res: ApiResponse<string>) => {
        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            showSuccessMsg("配置成功");
        }
    })
}
let currentRoleId = ref<number>(-1);
let currentSelectedIdList = ref<number[]>([])
const menuSetting = (index: number, row: Role) => {
    currentRoleId.value = row.id;
    menuListRequest.roleId = row.id;
    getSelectedMenuListByRoleId(menuListRequest).then((res: ApiResponse<number[]>) => {
        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            currentSelectedIdList.value = [];
            if (res.data) {
                res.data.forEach(element => {
                    currentSelectedIdList.value.push(element)
                });
            }
        }
    });
    menuSettingOuterVisible.value = true;
}
const handleSizeChange = (newSize: number) => {
    queryParams.pageSize = newSize;
    handleGetList();
}
const handleCurrentChange = (newPage: number) => {
    queryParams.pageNum = newPage;
    handleGetList();
}
const handleUpdate = (row: Role) => {}
const handleGetList = () => {
    pageRole(queryParams).then((res: ApiResponse<PageResponse<Role>>) => {
        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            let totalTemp = parseInt(res.data.total);
            pageData.totalNum = totalTemp;
            pageData.tableData = res.data.records;
            if (!props.roleSinglePage) {
                rowSelectTimeout();
            }
        }
    });
}
onMounted(() => {
    handleGetList();
})
const addFormRef = ref<FormInstance>()
const formSize = ref<ComponentSize>('default')
let addFormData = reactive<RoleAddRequest>({
    id: null,
    name: '',
    enName: '',
})
let rules = reactive<FormRules<RoleAddRequest>>({
    name: [{
        required: true,
        message: '请输入中文名称',
        trigger: 'change'
    }],
    enName: [{
        required: true,
        message: '请输入英文名称',
        trigger: 'change'
    }],
})
const submitAddForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            if (addOrUpdate.value) {
                addRole(addFormData).then((res: ApiResponse<string>) => {
                    if (res.status != 200) {
                        showErrorMsg(res.msg);
                    } else {
                        showSuccessMsg("新增成功");
                        handleGetList();
                    }
                })
            } else {
                updateRole(addFormData).then((res: ApiResponse<string>) => {
                    if (res.status != 200) {
                        showErrorMsg(res.msg);
                    } else {
                        showSuccessMsg("修改成功");
                        handleGetList();
                    }
                })
            }

        } else {
            console.log('error submit!', fields)
        }
    })
}
</script>
<style></style>